package com.ytjj.qmyx.supplychain.common.exception;

import com.ytjj.qmyx.supplychain.common.api.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

/**
 * 全局异常处理
 * 
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @Value("${spring.application.name}")
    private String serverName;

    @Value("${spring.profiles.active}")
    private String profiles;

    @ResponseBody
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public CommonResult paramExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult exceptions = e.getBindingResult();
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                FieldError fieldError = (FieldError) errors.get(0);
                return CommonResult.failed(fieldError.getDefaultMessage());
            }
        }
        return CommonResult.failed(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = ApiException.class)
    public CommonResult handle(ApiException e) {
        if (e.getErrorCode() != null) {
            return CommonResult.failed(e.getErrorCode());
        }
        return CommonResult.failed(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = IllegalArgumentException.class)
    public CommonResult handle(IllegalArgumentException e) {
        return CommonResult.failed(e.getMessage());
    }


    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public CommonResult handle(Exception e) {
        e.printStackTrace();
        log.error("程序出现异常：e:{}",getExceptionToString(e));
//        if("pd".equals(profiles) && !getExceptionToString(e).contains("Broken pipe")) {
//            DingDingWebHookUtil.sendPostByMessage("["+serverName+"]"+getExceptionToString(e));
//        }
        return CommonResult.failed("您的操作过于频繁，喝杯茶休息一下吧~");
    }

    @ResponseBody
    @ExceptionHandler(value = Error.class)
    public CommonResult handle(Error e) {
        log.error("程序出现异常：e:{}",getExceptionToString(e));
//        if("pd".equals(profiles) && !getExceptionToString(e).contains("Broken pipe")){
//            DingDingWebHookUtil.sendPostByMessage("["+serverName+"]"+getExceptionToString(e));
//        }
        return CommonResult.failed("您的操作过于频繁，喝杯茶休息一下吧~");
    }

    @ResponseBody
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public CommonResult handle(MissingServletRequestParameterException e){
        log.error("程序出现异常：e:{}",getExceptionToString(e));
        return CommonResult.failed("参数错误");
    }

    @ResponseBody
    @ExceptionHandler(value = UnauthorizedException.class)
    public CommonResult handle(UnauthorizedException e){
        log.error("暂无权限：e:{}",getExceptionToString(e));
        return CommonResult.failed("您暂无访问权限,请联系管理员,添加权限后重试!!!");
    }


    @ResponseBody
    @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    public CommonResult handle(MaxUploadSizeExceededException e){
        log.error("程序出现异常：e:{}",getExceptionToString(e));
        return CommonResult.failed("文件大小超过限制大小");
    }

    /**
     * 将 Exception 转化为 String
     */
    public static String getExceptionToString(Throwable e) {
        if (e == null){
            return "";
        }
        StringWriter stringWriter = new StringWriter();
        e.printStackTrace(new PrintWriter(stringWriter));
        return stringWriter.toString();
    }
}
